Java ORB Portability Interfaces

8


8.1 Introduction

The APIs specified here provide the minimal set of functionality to allow portable stubs and skeletons to be used with a Java ORB. The interoperability requirements for Java go beyond that of other languages. Because Java classes are often downloaded and come from sources that are independent of the ORB in which they will be used, it is essential to define the interfaces that the stubs and skeletons use. Otherwise, use of a stub (or skeleton) will require: either that it have been generated by a tool that was provided by the ORB vendor (or is compatible with the ORB being used), or that the entire ORB runtime be downloaded with the stub or skeleton. Both of these scenarios are unacceptable.

8.1.1 Design Goals

The design balances several goals:

Stubs and skeletons must have a small bytecode footprint in order to make downloading fast in a browser environment and to minimize memory requirements when bundled with a Java VM, particularly in specialized environments such as set-top boxes.
Obviously, the runtime performance of the generated stub code must be excellent. In particular, care must be taken to minimize temporary Java object creation during invocations in order to avoid Java VM garbage collection overhead.
The design does not require adding methods to user-defined types such as structures and exceptions to ensure that stubs and skeletons generated by IDL to Java compilers and reverse Java to IDL mapping tools are interoperable and binary compatible.

A very simple delegation scheme is specified here. Basically, it allows ORB vendors maximum flexibility for their ORB interfaces, as long as they implement the interface APIs. Of course vendors are free to add proprietary extensions to their ORB runtimes. Stubs and skeletons which require proprietary extensions will not necessarily be portable or interoperable and may require download of the corresponding runtime.

8.1.2 Portability Package

The APIs needed to implement portability are found in the org.omg.CORBA.portable package

The portability package contains interfaces and classes that are designed for and intended to be used by ORB implementors. It exposes the publicly defined APIs that are used to connect stubs and skeletons to the ORB.

8.2 Architecture

The stub and skeleton portability architecture allows the use of the DII and DSI as its portability layer. The mapping of the DII and DSI PIDL have operations that support the efficient implementation of portable stubs and skeletons

All stubs shall inherit from a common base class org.omg.CORBA.portable.ObjectImpl. The class is responsible for delegating shared functionality such as is_a() to the vendor specific implementation. This model provides for a variety of vendor dependent implementation choices, while reducing the client-side and server "code bloat".

All DSI-based skeletons inherit from org.omg.CORBA.DynamicImplementation.

8.3 Streamable APIs

The Streamable Interface API provides the support for the reading and writing of complex data types. It is implemented by static methods on the Helper classes. They are also used in the Holder classes for reading and writing complex data types passed as out and inout parameters.

package org.omg.CORBA.portable;
public interface Streamable {
	void _read(org.omg.CORBA.portable.InputStream istream);
	void _write(org.omg.CORBA.portable.OutputStream ostream);
	org.omg.CORBA.TypeCode _type();
}

8.4 Streaming APIs

The streaming APIs are Java interfaces that provide for the reading and writing of all of the mapped IDL types to and from streams. Their implementations are used inside the ORB to marshal parameters and to insert and extract complex datatypes into and from Anys.

The streaming APIs are found in the org.omg.CORBA.portable package.

The ORB object is used as a factory to create an output stream. An input stream may be created from an output stream.

package org.omg.CORBA;
interface ORB {
		OutputStream					create_output_stream();
};

package org.omg.CORBA.portable;
public abstract class InputStream {
	boolean					read_boolean();
	char					read_char();
	char					read_wchar();
	byte					read_octet();
	short					read_short();
	short					read_uhort();
	int					read_long();
	int					read_ulong();
	long					read_ulongong();
	float					read_float();
	double					read_double();
	String					read_string();
	String					read_wstring();
	void					read_boolean_array(boolean[] value,
											   int offset, int length);
	void					read_char_array(char[] value,
											   int offset, int length);
	void					read_wchar_array(char[] value,
											   int offset, int length);
	void					read_octet_array(byte[] value,
										   		int offset, int length);
	void					read_short_array(short[] value,
											   int offset, int length);
	void					read_ushort_array(short[] value,
											   int offset, int length);
	void					read_long_array(int[] value,
											   int offset, int length);
	void					read_ulong_array(int[] value,
											   int offset, int length);
	void					read_longlong_array(long[] value,
											   int offset, int length);
	void					read_ulonglong_array(long[] value,
											   int offset, int length);
	void					read_float_array(float[] value,
											   int offset, int length);
	void					read_double_array(double[] value,
											   int offset, int length);
	org.omg.CORBA.Object								read_Object();
	org.omg.CORBA.TypeCode								read_TypeCode();
	org.omg.CORBA.Any								read_any();
	org.omg.CORBA.Principal								read_Principal();
}

public abstract class OutputStream {
	InputStream			 create_input_stream();
	void write_boolean									(boolean value);
	void write_char									(char value);
	void write_wchar									(char value);
	void write_octet									(byte value);
	void write_short									(short value);
	void write_ushort									(short value);
	void write_long									(int value);
	void write_ulong									(int value);
	void write_long	long								(long value);
	void write_ulonglong									(long value);
	void write_float									(float value);
	void write_double									(double value);
	void write_string									(String value);
	void write_wstring									(String value);
	void write_boolean_array									(boolean[] value,
										 int offset, int length);
	void write_char_array									(char[] value,
										 int offset, int length);
	void write_wchar_array									(char[] value,
										 int offset, int length);
	void write_octet_array									(byte[] value,
										 int offset, int length);
	void write_short_array									(short[] value,
										 int offset, int length);
	void write_ushort_array									(short[] value,
										 int offset, int length);
	void write_long_array									(int[] value,
										 int offset, int length);
	void write_ulong_array									(int[] value,
										 int offset, int length);
	void write_longlong_array									(long[] value,
										 int offset, int length);
	void write_ulonglong_array									(long[] value,
										 int offset, int length);
	void write_float_array									(float[] value,
										 int offset, int length);
	void write_double_array									(double[] value,
										 int offset, int length);
	void write_Object							(org.omg.CORBA.Object value);
	void write_TypeCode							(org.omg.CORBA.TypeCode value);
	void write_any						 	(org.omg.CORBA.Any value);
	void write_Principal							(org.omg.CORBA.Principal value);
}

8.5 Portability Stub Interfaces

8.5.1 Stub Design

The stub class is implemented on top of the DII..

8.5.2 Portable ObjectImpl

The ObjectImpl class is the base class for stubs and skeletons. It provides the basic delegation mechanism.

The method _ids() returns an array of repository ids that an object implements. The string at the zero index shall represent the most derived interface. The last id, for the generic CORBA object (i.e. "IDL:omg.org/CORBA/Object:1.0"), is implied and not present.

package org.omg.CORBA.portable;
abstract public class ObjectImpl implements
										 org.omg.CORBA.Object {
	private Delegate __delegate;
	public Delegate _get_delegate() {
		if (__delegate == null) {
			throw new org.omg.CORBA.BAD_OPERATION();
		}
		return _delegate;
	}
	public void _set_delegate(Delegate delegate) {
		__delegate = delegate;
	}
	String[] _ids() {...}
// methods for standard CORBA stuff
	public org.omg.CORBA.ImplementationDef
										_get_implementation() {
		return _get_delegate().get_implementation(this);
	}
	public org.omg.CORBA.InterfaceDef
										_get_interface() {
		return _get_delegate().get_interface(this);
	}
	public org.omg.CORBA.Object _duplicate() {
		return _get_delegate().duplicate(this);
	}
	public void _release() {
		return _get_delegate().release(this);
	}
	public boolean _is_a(String repository_id) {
		return _get_delegate().is_a(this, repository_id);
	}
	public boolean _is_equivalent(org.omg.CORBA.Object rhs) {
		return _get_delegate().is_equivalent(this, rhs);
	}
	public boolean _non_existent() {
		return _get_delegate().non_existent(this);
	}
	public int _hash(int maximum) {
		return _get_delegate().hash(this, maximum);
	}
	public Request _request(String operation) {
		return _get_delegate().request(this, operation);
	}
	public org.omg.CORBA.Request _create_request(
						org.omg.CORBA.Context ctx,
                 String operation,
                 org.omg.CORBA.NVList arg_list,
                 org.omg.CORBA.NamedValue result) {
		return _get_delegate().create_request(this, ctx,
								operation, arg_list, result);
	}
	public Request _create_request(
							org.omg.CORBA.Context ctx,
                   String operation,
                   org.omg.CORBA.NVList arg_list,
                   org.omg.CORBA.NamedValue result,
                     org.omg.CORBA.ExceptionList exceptions,
                   org.omg.CORBA.ContextList contexts) {
		return _get_delegate().create_request(ctx, operation,
							arg_list, result,exceptions, contexts);
	}
}

8.6 Delegate

The delegate class provides the ORB vendor specific implementation of CORBA object.

// Java
package org.omg.CORBA.portable;
public abstract class Delegate {
	org.omg.CORBA ImplementationDef get_implementation(
								org.omg.CORBA.Object self);
	org.omg.CORBA.InterfaceDef get_interface(
								org.omg.CORBA.Object self);
	org.omg.CORBA.Object duplicate(
								org.omg.CORBA.Object self);
	void release(org.omg.CORBA.Object self);
	boolean is_a(org.omg.CORBA.Object self,
								String repository_id);
	boolean non_existent(org.omg.CORBA.Object self);
	boolean is_equivalent(org.omg.CORBA.Object self,
								org.omg.CORBA.Object rhs);
	org.omg.CORBA.Request hash(org.omg.CORBA.Object self
								int max);
	org.omg.CORBA.Request request(org.omg.CORBA.Object self,
								String operation);
	org.omg.CORBA.Request create_request(
								org.omg.CORBA.Object self,
								org.omg.CORBA.Context ctx,
								String operation,
								org.omg.CORBA.NVList arg_list,
								org.omg.CORBA.NamedValue result);
	org.omg.CORBA.Request create_request(
								org.omg.CORBA.Object self,
								org.omg.CORBA.Context ctx,
								String operation,
								org.omg.CORBA.NVList arg_list,
								org.omg.CORBA.NamedValue result,
								org.omg.CORBA.ExceptionList excepts,
								org.omg.CORBA.ContextList contexts);
}

8.7 Skeleton

The skeleton uses the DynamicImplementation (seeSection 6.10, "ServerRequest and Dynamic Implementation").

See Section 7.2.2, "Servant Class" for more information.

8.8 ORB Initialization

The ORB class represents an implementation of a CORBA ORB. Vendors specfic ORB implementations can extend this class to add new features.

There are several cases to consider when creating the ORB instance. An important factor is whether an applet in a browser or an stand-alone Java application is being used.

In any event, when creating an ORB instance, the class names of the ORB implementation are located using the following search order:

8.8.1 Standard Properties

The OMG standard properties are defined in the following table.



Table  8-1 Standard ORB properties

Property Name
Property Value

org.omg.CORBA.ORBClass

class name of an ORB implementation

org.omg.CORBA.ORBSingletonClass

class name of the singleton ORB implementation

8.8.2 ORB Initialization Methods

There are three forms of initialization as shown below. In addition the actual ORB implementation (subclassed from ORB) must implement the set_parameters() methods so that the initialization parameters will be passed into the ORB from the initialization methods.

// Java
package org.omg.CORBA;
abstract public class ORB {
	// Application init	
	public static ORB init(Strings[] args,
									java.util.Properties props) {
		set_parameters(args, props);
		...
		}
	// Applet init	
	public static ORB init(Applet app,
									java.util.Properties props) {
		set_parameters(app, props);
		...
		}
	// Default (singleton) init	
	public static ORB init()
		{...}
	// Implemented by subclassed ORB implementations
	//	and called by init methods to pass in their params
	public protected void set_parameters(Strings[] args,
									java.util.Properties props)
		{...}
	public protected void set_parameters(Applet app,
									java.util.Properties props)
		{...}
}

8.8.2.1 Default initialization

The default initializaton method returns the singleton ORB. If called multiple times it will always return the same the Java object.

For security reasons, if called from a Java applet, the ORB may only be used to create typecodes. An attempt to invoke other "regular" ORB operations shall raise a system exception.

If called from an application a fully functional ORB object is returned.

8.8.2.2 Application initialization

The application initialization method should be used from a stand-alone Java application. It is passed a array of strings which are the command arguments and a list of Java properties. Either the argument array or the properties may be null.

It returns a new fully functional ORB Java object each time it is called.

8.8.2.3 Applet inititialization

The applet initialization method should be used from an applet. It is passed "the applet" and a list of Java properties. Either the applet or the properties may be null.

It returns a new fully functional ORB Java object each time it is called.